<html>
<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<head>
<title>Section 15.6.&nbsp; XSI IPC</title>
<link rel="STYLESHEET" type="text/css" href="images/style.css">
<link rel="STYLESHEET" type="text/css" href="images/docsafari.css">
</head>
<body>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch15lev1sec5.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch15lev1sec7.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
<br><table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td valign="top"><a name="ch15lev1sec6"></a>
<h3 class="docSection1Title">15.6. XSI IPC</h3>
<p class="docText">The three types of IPC that we call XSI IPCmessage queues, semaphores, and shared memoryhave many similarities. In this section, we cover these similar features; in the following sections, we look at the specific functions for each of the three IPC types.</P>
<blockquote>
<p class="docText">The XSI IPC functions are based closely on the System V IPC functions. These three types of IPC originated in the 1970s in an internal AT&amp;T version of the UNIX System called &quot;Columbus UNIX.&quot; These IPC features were later added to System V. They are often criticized for inventing their own namespace instead of using the file system.</P>
<p class="docText">Recall from <a class="docLink" href="ch15lev1sec1.html#ch15fig01">Figure 15.1</a> that message queues, semaphores, and shared memory are defined as XSI extensions in the Single UNIX Specification.</p>
</blockquote>
<a name="ch15lev2sec1"></a>
<H4 class="docSection2Title">15.6.1. Identifiers and Keys</H4>
<p class="docText">Each <span class="docEmphasis">IPC structure</span> (message queue, semaphore, or shared memory segment) in the kernel is referred to by a non-negative integer <span class="docEmphasis">identifier</span>. To send or fetch a message to or from a message queue, for example, all we need know is the identifier for the queue. Unlike file descriptors, IPC identifiers are not small integers. Indeed, when a given IPC structure is created and then removed, the identifier associated with that structure continually increases until it reaches the maximum positive value for an integer, and then wraps around to 0.</P>
<p class="docText">The identifier is an internal name for an IPC object. Cooperating processes need an external naming scheme to be able to rendezvous using the same IPC object. For this purpose, an IPC object is associated with a <span class="docEmphasis">key</span> that acts as an external name.</p>
<p class="docText">Whenever an IPC structure is being created (by calling <tt>msgget</tt>, <tt>semget</tt>, or <tt>shmget</tt>), a key must be specified. The data type of this key is the primitive system data type <tt>key_t</tt>, which is often defined as a long integer in the header <tt>&lt;sys/types.h&gt;</tt>. This key is converted into an identifier by the kernel.</P>
<p class="docText">There are various ways for a client and a server to rendezvous at the same IPC structure.</P>
<div style="font-weight:bold"><ol class="docList" type="1"><LI><div style="font-weight:normal"><p class="docList"><a name="idd1e112904"></a><a name="idd1e112909"></a><a name="idd1e112914"></a><a name="idd1e112919"></a><a name="idd1e112926"></a><a name="idd1e112931"></a><a name="idd1e112936"></a>The server can create a new IPC structure by specifying a key of <tt>IPC_PRIVATE</tt> and store the returned identifier somewhere (such as a file) for the client to obtain. The key <tt>IPC_PRIVATE</tt> guarantees that the server creates a new IPC structure. The disadvantage to this technique is that file system operations are required for the server to write the integer identifier to a file, and then for the clients to retrieve this identifier later.</p><p class="docList">The <tt>IPC_PRIVATE</tt> key is also used in a parentchild relationship. The parent creates a new IPC structure specifying <tt>IPC_PRIVATE</tt>, and the resulting identifier is then available to the child after the <tt>fork</tt>. The child can pass the identifier to a new program as an argument to one of the <tt>exec</tt> functions.</P></div></li><LI><div style="font-weight:normal"><p class="docList">The client and the server can agree on a key by defining the key in a common header, for example. The server then creates a new IPC structure specifying this key. The problem with this approach is that it's possible for the key to already be associated with an IPC structure, in which case the <tt>get</tt> function (<tt>msgget</tt>, <tt>semget</tt>, or <tt>shmget</tt>) returns an error. The server must handle this error, deleting the existing IPC structure, and try to create it again.</P></div></LI><li><div style="font-weight:normal"><p class="docList">The client and the server can agree on a pathname and project ID (the project ID is a character value between 0 and 255) and call the function <tt>ftok</tt> to convert these two values into a key. This key is then used in step 2. The only service provided by <tt>ftok</tt> is a way of generating a key from a pathname and project ID.</P></div></LI></ol></div>
<a name="inta85"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="none" cellpadding="5"><colgroup><col width="500"></colgroup><thead></thead><TR><TD class="docTableCell" align="left" valign="top"><p class="docText">
<pre>
#include &lt;sys/ipc.h&gt;

key_t ftok(const char *<span class="docEmphItalicAlt">path</span>, int <span class="docEmphItalicAlt">id</span>);
</pre><br>

</p></td></tr><TR><td class="docTableCell" align="right" valign="top"><p class="docText">Returns: key if OK, <tt>(key_t)</tt>-1 on error</P></td></TR></table></p><br>
<p class="docText">The <span class="docEmphasis">path</span> argument must refer to an existing file. Only the lower 8 bits of <span class="docEmphasis">id</span> are used when generating the key.</p>
<p class="docText">The key created by <tt>ftok</tt> is usually formed by taking parts of the <tt>st_dev</tt> and <tt>st_ino</tt> fields in the <tt>stat</tt> structure (<a class="docLink" href="ch04lev1sec2.html#ch04lev1sec2">Section 4.2</a>) corresponding to the given pathname and combining them with the project ID. If two pathnames refer to two different files, then <tt>ftok</tt> usually returns two different keys for the two pathnames. However, because both i-node numbers and keys are often stored in long integers, there can be information loss creating a key. This means that two different pathnames to different files can generate the same key if the same project ID is used.</p>
<p class="docText">The three <tt>get</tt> functions (<tt>msgget</tt>, <tt>semget</tt>, and <tt>shmget</tt>) all have two similar arguments: a <span class="docEmphasis">key</span> and an integer <span class="docEmphasis">flag</span>. A new IPC structure is created (normally, by a server) if either <span class="docEmphasis">key</span> is <tt>IPC_PRIVATE</tt> or <span class="docEmphasis">key</span> is not currently associated with an IPC structure of the particular type and the <tt>IPC_CREAT</tt> bit of <span class="docEmphasis">flag</span> is specified. To reference an existing queue (normally done by a client), <span class="docEmphasis">key</span> must equal the key that was specified when the queue was created, and <tt>IPC_CREAT</tt> must not be specified.</p>
<p class="docText">Note that it's never possible to specify <tt>IPC_PRIVATE</tt> to reference an existing queue, since this special <span class="docEmphasis">key</span> value always creates a new queue. To reference an existing queue that was created with a <span class="docEmphasis">key</span> of <tt>IPC_PRIVATE</tt>, we must know the associated<a name="idd1e113118"></a><a name="idd1e113123"></a><a name="idd1e113128"></a><a name="idd1e113133"></a><a name="idd1e113138"></a><a name="idd1e113143"></a><a name="idd1e113148"></a><a name="idd1e113153"></a><a name="idd1e113158"></a><a name="idd1e113163"></a><a name="idd1e113168"></a><a name="idd1e113173"></a><a name="idd1e113178"></a><a name="idd1e113183"></a><a name="idd1e113188"></a><a name="idd1e113193"></a><a name="idd1e113198"></a><a name="idd1e113201"></a><a name="idd1e113206"></a>identifier and then use that identifier in the other IPC calls (such as <tt>msgsnd</tt> and <tt>msgrcv</tt>), bypassing the <tt>get</tt> function.</p>
<p class="docText">If we want to create a new IPC structure, making sure that we don't reference an existing one with the same identifier, we must specify a <span class="docEmphasis">flag</span> with both the <tt>IPC_CREAT</tt> and <tt>IPC_EXCL</tt> bits set. Doing this causes an error return of <tt>EEXIST</tt> if the IPC structure already exists. (This is similar to an <tt>open</tt> that specifies the <tt>O_CREAT</tt> and <tt>O_EXCL</tt> flags.)</p>

<a name="ch15lev2sec2"></a>
<h4 class="docSection2Title">15.6.2. Permission Structure</h4>
<p class="docText">XSI IPC associates an <tt>ipc_perm</tt> structure with each IPC structure. This structure defines the permissions and owner and includes at least the following members:</p>

<pre>
   struct ipc_perm {
     uid_t  uid;  /* owner's effective user id */
     gid_t  gid;  /* owner's effective group id */
     uid_t  cuid; /* creator's effective user id */
     gid_t  cgid; /* creator's effective group id */
     mode_t mode; /* access modes */
     .
     .
     .
   };
</pre><br>

<p class="docText">Each implementation includes additional members. See <tt>&lt;sys/ipc.h&gt;</tt> on your system for the complete definition.</p>
<p class="docText">All the fields are initialized when the IPC structure is created. At a later time, we can modify the <tt>uid</tt>, <tt>gid</tt>, and <tt>mode</tt> fields by calling <tt>msgctl</tt>, <tt>semctl</tt>, or <tt>shmctl</tt>. To change these values, the calling process must be either the creator of the IPC structure or the superuser. Changing these fields is similar to calling <tt>chown</tt> or <tt>chmod</tt> for a file.</p>
<p class="docText">The values in the <tt>mode</tt> field are similar to the values we saw in <a class="docLink" href="ch04lev1sec5.html#ch04fig06">Figure 4.6</a>, but there is nothing corresponding to execute permission for any of the IPC structures. Also, message queues and shared memory use the terms <span class="docEmphasis">read</span> and <span class="docEmphasis">write</span>, but semaphores use the terms <span class="docEmphasis">read</span> and <span class="docEmphasis">alter</span>. <a class="docLink" href="#ch15fig24">Figure 15.24</a> shows the six permissions for each form of IPC.</p>
<a name="ch15fig24"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="groups" cellpadding="5"><caption><h5 class="docTableTitle">Figure 15.24. XSI IPC permissions</h5></caption><colgroup><col width="150"><col width="75"></colgroup><thead><TR><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Permission</span></P></th><th class="bottomBorder thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Bit</span></p></th></TR></thead><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">user-read</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText"><tt>0400</tt></P></td></TR><tr><TD class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">user-write (alter)</P></TD><td class="bottomBorder" align="center" valign="top"><p class="docText"><tt>0200</tt>
</P></TD></tr><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">group-read</p></td><td class="docTableCell" align="center" valign="top"><p class="docText"><tt>0040</tt></p></TD></tr><TR><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">group-write (alter)</P></td><td class="bottomBorder" align="center" valign="top"><p class="docText"><tt>0020</tt></p></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText">other-read</p></td><td class="docTableCell" align="center" valign="top"><p class="docText"><tt>0004</tt></p></td></tr><tr><td class="rightBorder bottomBorder" align="left" valign="top"><p class="docText">other-write (alter)</p></td><TD class="bottomBorder" align="center" valign="top"><p class="docText"><tt>0002</tt>
</P></td></TR></table></P><BR>
<p class="docText">Some implementations define symbolic constants to represent each permission, however, these constants are not standardized by the Single UNIX Specification.</p>

<a name="ch15lev2sec3"></a>
<H4 class="docSection2Title">15.6.3. Configuration Limits</H4>
<p class="docText"><a name="idd1e113440"></a><a name="idd1e113443"></a><a name="idd1e113446"></a><a name="idd1e113451"></a><a name="idd1e113456"></a><a name="idd1e113459"></a><a name="idd1e113464"></a><a name="idd1e113469"></a><a name="idd1e113472"></a><a name="idd1e113475"></a><a name="idd1e113480"></a><a name="idd1e113483"></a><a name="idd1e113488"></a><a name="idd1e113493"></a><a name="idd1e113498"></a><a name="idd1e113503"></a><a name="idd1e113508"></a><a name="idd1e113513"></a><a name="idd1e113516"></a><a name="idd1e113521"></a><a name="idd1e113526"></a>All three forms of XSI IPC have built-in limits that we may encounter. Most of these limits can be changed by reconfiguring the kernel. We describe the limits when we describe each of the three forms of IPC.</P>
<blockquote>
<p class="docText">Each platform provides its own way to report and modify a particular limit. FreeBSD 5.2.1, Linux 2.4.22, and Mac OS X 10.3 provide the <tt>sysctl</tt> command to view and modify kernel configuration parameters. On Solaris 9, changes to kernel configuration parameters are made by modifying the file <tt>/etc/system</tt> and rebooting.</p>
<p class="docText">On Linux, you can display the IPC-related limits by running <tt>ipcs -l</tt>. On FreeBSD, the equivalent command is <tt>ipcs -T</tt>. On Solaris, you can discover the tunable parameters by running <tt>sysdef -i</tt>.</P>
</blockquote>

<a name="ch15lev2sec4"></a>
<h4 class="docSection2Title">15.6.4. Advantages and Disadvantages</H4>
<p class="docText">A fundamental problem with XSI IPC is that the IPC structures are systemwide and do not have a reference count. For example, if we create a message queue, place some messages on the queue, and then terminate, the message queue and its contents are not deleted. They remain in the system until specifically read or deleted by some process calling <tt>msgrcv</tt> or <tt>msgctl</tt>, by someone executing the <tt>ipcrm</tt>(1) command, or by the system being rebooted. Compare this with a pipe, which is completely removed when the last process to reference it terminates. With a FIFO, although the name stays in the file system until explicitly removed, any data left in a FIFO is removed when the last process to reference the FIFO terminates.</P>
<p class="docText">Another problem with XSI IPC is that these IPC structures are not known by names in the file system. We can't access them and modify their properties with the functions we described in <a class="docLink" href="ch03.html#ch03">Chapters 3</a> and <a class="docLink" href="ch04.html#ch04">4</a>. Almost a dozen new system calls (<tt>msgget</tt>, <tt>semop</tt>, <tt>shmat</tt>, and so on) were added to the kernel to support these IPC objects. We can't see the IPC objects with an <tt>ls</tt> command, we can't remove them with the <tt>rm</tt> command, and we can't change their permissions with the <tt>chmod</tt> command. Instead, two new commands <tt>ipcs</tt>(1) and <tt>ipcrm</tt>(1)were added.</P>
<p class="docText">Since these forms of IPC don't use file descriptors, we can't use the multiplexed I/O functions (<tt>select</tt> and <tt>poll</tt>) with them. This makes it harder to use more than one of these IPC structures at a time or to use any of these IPC structures with file or device I/O. For example, we can't have a server wait for a message to be placed on one of two message queues without some form of busywait loop.</p>
<p class="docText">An overview of a transaction processing system built using System V IPC is given in Andrade, Carges, and Kovach [<a class="docLink" href="bib01.html#biblio01_004">1989</a>]. They claim that the namespace used by System V IPC (the identifiers) is an advantage, not a problem as we said earlier, because using identifiers allows a process to send a message to a message queue with a single function call (<tt>msgsnd</tt>), whereas other forms of IPC normally require an <tt>open</tt>, <tt>write</tt>, and <tt>close</tt>. This argument is false. Clients still have to obtain the identifier for the server's queue somehow, to avoid using a key and calling <tt>msgget</tt>. The identifier assigned to a particular queue depends on how many other message queues exist when the queue is created and how many times the table in the kernel assigned to the new <a name="idd1e113639"></a><a name="idd1e113642"></a><a name="idd1e113645"></a>queue has been used since the kernel was bootstrapped. This is a dynamic value that can't be guessed or stored in a header. As we mentioned in <a class="docLink" href="#ch15lev2sec1">Section 15.6.1</a>, minimally a server has to write the assigned queue identifier to a file for its clients to read.</P>
<p class="docText">Other advantages listed by these authors for message queues are that they're reliable, flow controlled, record oriented, and can be processed in other than first-in, first-out order. As we saw in <a class="docLink" href="ch14lev1sec4.html#ch14lev1sec4">Section 14.4</a>, the STREAMS mechanism also possesses all these properties, although an <tt>open</tt> is required before sending data to a stream, and a <tt>close</tt> is required when we're finished. <a class="docLink" href="#ch15fig25">Figure 15.25</a> compares some of the features of these various forms of IPC.</P>
<a name="ch15fig25"></a><p><table cellspacing="0" class="allBorders" border="1" RULES="groups" cellpadding="5"><caption><H5 class="docTableTitle">Figure 15.25. Comparison of features of various forms of IPC</H5></caption><colgroup><col width="170"><col width="70"><col width="70"><col width="70"><col width="70"><col width="70"></colgroup><thead><tr><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">IPC type</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Connectionless?</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Reliable?</span></p></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Flow control?</span></P></th><th class="rightBorder bottomBorder thead" scope="col" align="center" valign="middle"><p class="docText"><span class="docEmphRoman">Records?</span></p></th><th class="bottomBorder thead" scope="col" align="center" valign="top"><p class="docText"><span class="docEmphRoman">Message types or priorities?</span></P></th></tr></thead><TR><td class="rightBorder" align="left" valign="top"><p class="docText">message queues</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">no</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">yes</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">yes</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">yes</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">yes</p></TD></TR><tr><TD class="rightBorder" align="left" valign="top"><p class="docText">STREAMS</P></TD><td class="rightBorder" align="center" valign="top"><p class="docText">no</P></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">yes</p></TD><td class="rightBorder" align="center" valign="top"><p class="docText">yes</P></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">yes</p></TD><TD class="docTableCell" align="center" valign="top"><p class="docText">yes</p></TD></TR><tr><td class="rightBorder" align="left" valign="top"><p class="docText">UNIX domain stream socket</p></td><TD class="rightBorder" align="center" valign="top"><p class="docText">no</p></TD><td class="rightBorder" align="center" valign="top"><p class="docText">yes</P></td><td class="rightBorder" align="center" valign="top"><p class="docText">yes</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">no</p></td><td class="docTableCell" align="center" valign="top"><p class="docText">no</p></td></tr><tr><td class="rightBorder" align="left" valign="top"><p class="docText">UNIX domain datagram socket</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">yes</p></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">yes</p></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">no</P></td><TD class="rightBorder" align="center" valign="top"><p class="docText">yes</P></TD><td class="docTableCell" align="center" valign="top"><p class="docText">no</P></td></TR><TR><TD class="rightBorder" align="left" valign="top"><p class="docText">FIFOs (non-STREAMS)</p></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">no</p></TD><TD class="rightBorder" align="center" valign="top"><p class="docText">yes</p></td><td class="rightBorder" align="center" valign="top"><p class="docText">yes</p></TD><td class="rightBorder" align="center" valign="top"><p class="docText">no</P></td><TD class="docTableCell" align="center" valign="top"><p class="docText">no</p></td></tr></table></p><br>
<p class="docText">(We describe stream and datagram sockets in <a class="docLink" href="ch16.html#ch16">Chapter 16</a>. We describe UNIX domain sockets in <a class="docLink" href="ch17lev1sec3.html#ch17lev1sec3">Section 17.3</a>.) By &quot;connectionless,&quot; we mean the ability to send a message without having to call some form of an open function first. As described previously, we don't consider message queues connectionless, since some technique is required to obtain the identifier for a queue. Since all these forms of IPC are restricted to a single host, all are reliable. When the messages are sent across a network, the possibility of messages being lost becomes a concern. &quot;Flow control&quot; means that the sender is put to sleep if there is a shortage of system resources (buffers) or if the receiver can't accept any more messages. When the flow control condition subsides, the sender should automatically be awakened.</p>
<p class="docText">One feature that we don't show in <a class="docLink" href="#ch15fig25">Figure 15.25</a> is whether the IPC facility can automatically create a unique connection to a server for each client. We'll see in <a class="docLink" href="ch17.html#ch17">Chapter 17</a> that STREAMS and UNIX stream sockets provide this capability.</p>
<p class="docText">The next three sections describe each of the three forms of XSI IPC in detail.</p>


<a href="17021535.html"><img src="images/pixel.gif" alt="" width="1" height="1" border="0"></a><ul></ul></td></tr></table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr><td><div STYLE="MARGIN-LEFT: 0.15in;"><a href="toc.html"><img src="images/team.gif" width="60" height="17" border="0" align="absmiddle"  alt="Team BBL"></a></div></td>
<td align="right"><div STYLE="MARGIN-LEFT: 0.15in;">
<a href=ch15lev1sec5.html><img src="images/prev.gif" width="60" height="17" border="0" align="absmiddle" alt="Previous Page"></a>
<a href=ch15lev1sec7.html><img src="images/next.gif" width="60" height="17" border="0" align="absmiddle" alt="Next Page"></a>
</div></td></tr></table>
</body></html><br>
<table width="100%" cellspacing="0" cellpadding="0"
style="margin-top: 0pt; border-collapse: collapse;"> 
<tr> <td align="right" style="background-color=white; border-top: 1px solid gray;"> 
<a href="http://www.zipghost.com/" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">The CHM file was converted to HTM by Trial version of <b>ChmD<!--247-->ecompiler</b>.</a>
</TD>
</TR><tr>
<td align="right" style="background-color=white; "> 
<a href="http://www.etextwizard.com/download/cd/cdsetup.exe" target="_blank" style="font-family: Tahoma, Verdana;
 font-size: 11px; text-decoration: none;">Download <b>ChmDec<!--247-->ompiler</b> at: http://www.zipghost.com</a>
</TD></tr></table>
